#include "CyTimer.h"
#include "CyRoutine.h"

CyTimer::CyTimer(int delay)
{
	_delay = delay;
	_handler = NULL;
	_id = 0;

	LPCTSTR ClsName = L"CyTimer";
	HINSTANCE hInstance = GetModuleHandle(NULL);
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= CyTimerProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= sizeof(LONG);
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= 0;
	wcex.lpszClassName	= ClsName;
	wcex.hIconSm		= 0;

	int err = RegisterClassEx(&wcex);

	_hWnd = CreateWindow(ClsName, 0, WS_OVERLAPPEDWINDOW,
		0, 0, 0, 0, NULL, NULL, hInstance, NULL);

	SetWindowLong(_hWnd, 0, (LONG) this);
}

CyTimer::~CyTimer(void)
{
	Stop();

	SetWindowLong(_hWnd, 0, 0);
	DestroyWindow(_hWnd);

	if (_handler != NULL)
		delete _handler;
}

CyTimer& CyTimer::SetDelay(unsigned int delay)
{
	_delay = delay;

	return *this;
}

CyTimer& CyTimer::Start()
{
	if (_id == 0)
	{
		_id = SetTimer(_hWnd, 0, _delay, NULL);

		if (_id == 0)
		{
			CY_THROW("Cannot create new timer");
		}
	}

	return *this;
}

CyTimer& CyTimer::Stop()
{
	if (_id != 0)
	{
		KillTimer(_hWnd, _id);
		_id = 0;
	}

	return *this;
}

// Call back
LRESULT CALLBACK CyTimerProc(HWND hwnd,
	UINT message, WPARAM wParam, LPARAM lParam)
{
	CyTimer * _this = (CyTimer *) GetWindowLong(hwnd, 0);

	switch (message)
	{
	case WM_TIMER:
		if (_this->_handler != NULL)
		{
			_this->_handler->Do(hwnd, message, lParam, wParam);
		}
		return 0;
	}

	return DefWindowProc (hwnd, message, wParam, lParam) ;
}